package de.hsb.ai.devil.ui;

import jade.core.AID;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.RowSorter;
import javax.swing.ScrollPaneConstants;
import javax.swing.WindowConstants;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.DefaultCaret;

import org.apache.log4j.Appender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.WriterAppender;
import org.apache.log4j.spi.LoggingEvent;

import de.hsb.ai.devil.agent.AgentManager;
import de.hsb.ai.devil.agent.DevilManagementAgent;
import de.hsb.ai.devil.agent.DevilMasterAgent;
import de.hsb.ai.devil.ui.components.DevilTableModel;
import de.hsb.ai.devil.ui.components.StartGameDialog;

public class ManagementGui extends JFrame implements WindowListener {
	
	enum Command {
		CREATE, START, EXIT, DELETE
	}
	
	private static final Logger logger = Logger.getLogger("management-gui");
	
	private Appender logAreaAppender = new WriterAppender() {
		@Override
		public void append(LoggingEvent event) {
			logArea.append(getLayout().format(event));
		}
	};

	private JTextArea logArea;
	private DevilTableModel agentTableModel;
	private JTable agentTable;
	
	private AgentManager manager;
	
	private ActionListener menuActionListener = new ActionListener() {
		
		@Override
		public void actionPerformed(ActionEvent e) {
			Command command = Command.valueOf(e.getActionCommand());
			switch (command) {
			case CREATE:
				createAgent();
				break;
			case START:
				startGame();
				break;
			case DELETE:
				deleteAgents();
				break;
			case EXIT:
				shutdown();
				break;
			}
			
		}


	};

	public ManagementGui(DevilManagementAgent devilManagementAgent){
		manager = devilManagementAgent;
		
		setSize(new Dimension(500, 400));
		setPreferredSize(new Dimension(500, 400));
		setResizable(false);
		
		BoxLayout thisLayout = new BoxLayout(getContentPane(), javax.swing.BoxLayout.Y_AXIS);
		getContentPane().setLayout(thisLayout);
		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		  
	    Toolkit toolkit = Toolkit.getDefaultToolkit();
	    Dimension ssize = toolkit.getScreenSize();
	    int x = (int) ( ssize.getWidth() - getWidth() ) / 2;
	    setLocation( x, 0 );		
		initGui();
		
		setupLogger();
	}
	
	protected void createAgent() {
		manager.createAgent();
	}
	
	private void startGame() {
		final int[] rows = agentTable.getSelectedRows();
		if(rows.length != 2){
			JOptionPane.showMessageDialog(this, "You have to select two agents!!!");
		}
		else {
//			manager.startGame(agentTableModel.getAID(rows[0]), agentTableModel.getAID(rows[1]));
			final StartGameDialog sgd = new StartGameDialog(agentTableModel.getAID(rows[0]), agentTableModel.getAID(rows[1]));
			sgd.setLocation(this.getLocation());
			sgd.setStartListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					AID p1 = agentTableModel.getAID(rows[0]);
					AID p2 = agentTableModel.getAID(rows[1]);
					//Switch players
					if (sgd.isSwitched()) {
						AID tmp = p1; 
						p1 = p2;
						p2 = tmp;
					}
					manager.startGame(p1, p2);
				}
			});
		}
		agentTable.getSelectionModel().removeIndexInterval(0, agentTable.getRowCount());
		
		
	}
	
	protected void deleteAgents(){
		int[] rows = agentTable.getSelectedRows();
		for(int i : rows){
			manager.deleteAgent((AID) agentTableModel.getValueAt(i, DevilTableModel.AID_INDEX));
		}
	}
	
	private void shutdown() {
		manager.shutdown();
	}

	private void initGui(){
		createMenuBar();
		createTable();
		add(Box.createRigidArea(new Dimension(420,20)));
		createStatusBar();

		pack();
	}
	
	private void setupLogger() {
		logAreaAppender.setLayout(new PatternLayout("[%t] %-5p %c %x - %m%n"));
		DevilManagementAgent.logger.addAppender(logAreaAppender);
		DevilMasterAgent.logger.addAppender(logAreaAppender);
		logger.addAppender(logAreaAppender);
	}
	
	private void createMenuBar(){
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		{
		JMenu jMenu1 = new JMenu();
			menuBar.add(jMenu1);
			jMenu1.setText("Manager");
			jMenu1.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/folder_go.png")));

			{
				JMenuItem m1 = new JMenuItem();
				jMenu1.add(m1);
				m1.setText("New Agent");
				m1.setActionCommand(Command.CREATE.name());
				m1.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/user_add.png")));
				m1.addActionListener(menuActionListener);
			}
			{
				JMenuItem m2 = new JMenuItem();
				jMenu1.add(m2);
				m2.setText("Start Game");
				m2.setActionCommand(Command.START.name());
				m2.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/group_go.png")));
				m2.addActionListener(menuActionListener);
			}
			{
				JMenuItem m3 = new JMenuItem();
				jMenu1.add(m3);
				m3.setText("Delete selected Agents");
				m3.setActionCommand(Command.DELETE.name());
				m3.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/delete.png")));
				m3.addActionListener(menuActionListener);
			}
			{
				JMenuItem m4 = new JMenuItem();
				jMenu1.add(m4);
				m4.setText("Shutdown");
				m4.setActionCommand(Command.EXIT.name());
				m4.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/cancel.png")));
				m4.addActionListener(menuActionListener);
			}
		}
	}
	
	private void createTable(){
		JLabel label_activeAgents = new JLabel("Active Agents");
		
		JScrollPane tableScrollPane = new JScrollPane();
		tableScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		tableScrollPane.setSize(new Dimension(200, 200));
		tableScrollPane.setMinimumSize(new Dimension(200, 200));
		{
			agentTable = new JTable();
			agentTableModel = new DevilTableModel();
			agentTable.setModel(agentTableModel);
			agentTable.setSize(new Dimension(200, 200));
			agentTable.setMinimumSize(new Dimension(200, 200));
			tableScrollPane.setViewportView(agentTable);
			
			agentTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
			manager.addHandler(agentTableModel);
			
		    RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(agentTableModel);

		    agentTable.setRowSorter(sorter);
		}
		add(label_activeAgents);
		add(tableScrollPane);
	}
	
	private void createStatusBar(){
		JLabel label_agentLog = new JLabel("Log");
		
		JScrollPane statusBarScrollPane = new JScrollPane();
		statusBarScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		statusBarScrollPane.setSize(new Dimension(200, 100));
		statusBarScrollPane.setMinimumSize(new Dimension(200, 100));
		{
			logArea = new JTextArea();
			logArea.setEditable(false);
			logArea.setSize(new Dimension(200, 100));
			logArea.setMinimumSize(new Dimension(200, 100));
			Font font = new Font("Monospaced", Font.TRUETYPE_FONT, 11);
			logArea.setFont(font);
			logArea.setForeground(Color.RED);
			
			DefaultCaret caret = (DefaultCaret)logArea.getCaret();
			caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

			statusBarScrollPane.setViewportView(logArea);
		}
		add(label_agentLog);
		add(statusBarScrollPane);
	}
	
	@Override
	public void windowOpened(WindowEvent e) { }

	@Override
	public void windowClosing(WindowEvent e) {}

	@Override
	public void windowClosed(WindowEvent e) {
		shutdown();
	}

	@Override
	public void windowIconified(WindowEvent e) {}

	@Override
	public void windowDeiconified(WindowEvent e) {}

	@Override
	public void windowActivated(WindowEvent e) {}

	@Override
	public void windowDeactivated(WindowEvent e) {}
}
